package com.ada;

import jdk.nashorn.api.scripting.ScriptObjectMirror;

import javax.script.*;
import java.util.List;

/**
 * Hello world!
 */
public class App {


    public void invokeFunction() throws ScriptException, NoSuchMethodException {
        ScriptEngine engine = getJavaScriptEngine();
        String scriptText = "function greet(name) { return 'Hello, ' + name; } ";
        engine.eval(scriptText);
        Invocable invocable = (Invocable) engine;
        Object o = invocable.invokeFunction("greet", "Alex");
        System.out.println(o);
    }

    public void invokeMethod() throws ScriptException, NoSuchMethodException {
        ScriptEngine engine = getJavaScriptEngine();
        String scriptText = "function main(name,modules) {modules.msg('ada'); return 'Hello, ' + name; } ";
        engine.eval(scriptText);
        Invocable invocable = (Invocable) engine;

        IModule modules = new ModuleImpl();

        Object o = invocable.invokeFunction("main", "Alex", modules);
        System.out.println(o);
    }

    public static void main(String[] args) {
        App app = new App();
        try {
            app.x();
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

    }

    private void x() throws ScriptException, NoSuchMethodException {

        ScriptEngine scriptEngine = getJavaScriptEngine();
        Bindings bind = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE);
        bind.put("log", Logger.getInstance());
        StringBuffer sb = new StringBuffer();
        sb.append("function main( modules) {modules.msg('ada');var x={};x.name=1;log.info(x);var result=  {};result.name='123';return result;}");
        scriptEngine.eval(sb.toString());

        Invocable invocable = (Invocable) scriptEngine;
        IModule modules = new ModuleImpl();
        try {
            Object result = invocable.invokeFunction("main", modules);
            if (result instanceof  ScriptObjectMirror){
                ScriptObjectMirror  mirror=(ScriptObjectMirror)result;
                System.out.println(mirror.get("name"));
            Object o=    mirror.eval("var a={};a.age=18;");
                System.out.println(o);
            }
          System.out.println(result);
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
    private void y() throws ScriptException, NoSuchMethodException {

        ScriptEngine scriptEngine = getJavaScriptEngine();
        Bindings bind = scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE);
        bind.put("log", Logger.getInstance());
        StringBuffer sb = new StringBuffer();
        sb.append("function main( modules) {modules.msg('ada');var result={};result.name='ada';result.age=15; return result;}");
        scriptEngine.eval(sb.toString());

        Invocable invocable = (Invocable) scriptEngine;
        IModule modules = new ModuleImpl();
        try {
            Object result = invocable.invokeFunction("main", modules);
            System.out.println(result);
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
    public ScriptEngine getJavaScriptEngine() {
        ScriptEngineManager mgr = new ScriptEngineManager();
        ScriptEngineManager manager = new ScriptEngineManager();
        List<ScriptEngineFactory> factories = manager.getEngineFactories();
        for (ScriptEngineFactory f : factories) {
            System.out.println("*****************************");
            System.out.println(f.getEngineName());
            System.out.println(f.getEngineVersion());
            System.out.println(f.getLanguageName());
            System.out.println(f.getLanguageVersion());
            System.out.println(f.getExtensions());
            System.out.println(f.getMimeTypes());
            System.out.println(f.getNames());
        }

        ScriptEngine scriptEngine = mgr.getEngineByName("nashorn");
        return scriptEngine;
    }
}
